package com.gdufe.seckill.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gdufe.common.feign.ProductFeign;
import com.gdufe.common.utils.PageUtils;
import com.gdufe.common.entity.Product;
import com.gdufe.seckill.dao.RelationDao;
import com.gdufe.seckill.entity.RelationEntity;
import com.gdufe.seckill.entity.SessionEntity;
import com.gdufe.seckill.service.RelationUserService;
import com.gdufe.seckill.service.SessionUserService;
import com.gdufe.seckill.vo.SeckilOrderFormVo;
import com.gdufe.seckill.vo.SeckillProductVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service("RelationUserService")
public class RelationUserServiceImpl extends ServiceImpl<RelationDao, RelationEntity> implements RelationUserService {

    @Autowired
    private ProductFeign productFeign;
    @Autowired
    private SessionUserService sessionUserService;
    @Autowired
    private RedisTemplate redisTemplate;

    public  static final String SEC_KILL_GOODS_KEY="seckillgoods";

    //模块一旦启动就往redis里增加秒杀商品
    @EventListener
    public void contextRefeshedEventListener(ContextRefreshedEvent contextRefreshedEvent){
        if(redisTemplate == null){
            return;
        }
        //获取操作redis hash类型的操作类
        BoundHashOperations<String,Object ,Object> hashOperations = redisTemplate.boundHashOps(SEC_KILL_GOODS_KEY);

        QueryWrapper<RelationEntity> wrapper = new QueryWrapper<>();
        //若该秒杀商品被启用则展示
        wrapper.eq("seckill_status",1);
        List<RelationEntity> relationEntities = this.list(wrapper);
        for (RelationEntity item:relationEntities) {
            hashOperations.put(item.getId().toString(),item.getSeckillCount().toString());
        }
    }
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        //获取操作redis hash类型的操作类
        BoundHashOperations<String,Object ,Object> hashOperations = redisTemplate.boundHashOps(SEC_KILL_GOODS_KEY);

        String key = (String) params.get("key");
        String sessionId = (String) params.get("sessionId");
        String productName = (String)params.get("productName");

        QueryWrapper<RelationEntity> wrapper = new QueryWrapper<>();
        //若该秒杀商品被启用则展示
        wrapper.eq("seckill_status",1);
        //若用户有输入查找参数，则根据秒杀商品的商品id或秒杀id进行查找
        if(!key.isEmpty()){
            wrapper.eq("id",key).or().eq("product_id",key);
        }
        //若用户有输入场次参数，则根据秒杀商品的场次id进行查找
        if(!sessionId.isEmpty()){
            wrapper.eq("session_id",sessionId);
        }

        List<RelationEntity> relationEntities = this.list(wrapper);
        List<SeckillProductVo> vos = new ArrayList<>();
        //若用户没有输入商品名称进行查找，则展示所有可筛选后的商品
        if(StringUtils.isEmpty(productName)){
            vos = relationEntities.stream().map(item->{
                SeckillProductVo vo = new SeckillProductVo();
                BeanUtils.copyProperties(item,vo);
                //根据商品id远程调用商品信息
                Product product = productFeign.userSelectById(item.getProductId()).getData(new TypeReference<Product>(){});
                vo.setProductName(product.getName());
                SessionEntity session = sessionUserService.getById(item.getSessionId());
                Date date = new Date();
                //获取redis里商品库存
                int cnt = Integer.valueOf(hashOperations.get(vo.getId().toString()).toString());
                vo.setSeckillCount(Integer.valueOf(hashOperations.get(vo.getId().toString()).toString()) );
                //判断当前时间是否在商品场次时间段内
                if(date.after(session.getStartTime())&&date.before(session.getEndTime())){
                    vo.setBuyStatus(1);
                }else{
                    vo.setBuyStatus(0);
                }
                return vo;
            }).collect(Collectors.toList());
        }//若用户入商品名称进行查找，则再次对筛选后的商品进行筛查，展示对应商品
        else {
            for (RelationEntity item:relationEntities) {
                Product product = productFeign.userSelectById(item.getProductId()).getData(new TypeReference<Product>(){});
                if(product.getName().equals(productName)){
                    SeckillProductVo vo = new SeckillProductVo();
                    BeanUtils.copyProperties(item,vo);
                    vo.setProductName(product.getName());
                    SessionEntity session = sessionUserService.getById(item.getSessionId());
                    Date date = new Date();
                    vo.setSeckillCount(Integer.valueOf(hashOperations.get(vo.getId().toString()).toString()));
                    System.out.println(hashOperations.get(vo.getId().toString()));
                    //判断当前时间是否在秒杀商品场次时间段内
                    if(date.after(session.getStartTime())&&date.before(session.getEndTime())){
                        vo.setBuyStatus(1);
                    }else{
                        vo.setBuyStatus(0);
                    }
                    vos.add(vo);
                }
            }
        }
        //分页
        Integer pageIndex = Integer.parseInt(params.get("page").toString());
        Integer limit = Integer.parseInt(params.get("limit").toString());
        int from = (pageIndex - 1) * limit;
        int to = from + limit > vos.size() ? vos.size() : from + limit;
        List<SeckillProductVo> vos1 = new ArrayList<>(vos.subList(from, to));
        IPage<SeckillProductVo> page = new Page<>(pageIndex, limit);
        page.setRecords(vos1);
        page.setTotal(vos.size());
        page.setPages(vos.size() % limit > 0 ? vos.size() / limit + 1 : vos.size() / limit);

        return new PageUtils(page);
    }

    @Override
    public SeckilOrderFormVo init(Integer id) {
        //获取操作redis hash类型的操作类
        BoundHashOperations<String,Object ,Object> hashOperations = redisTemplate.boundHashOps(SEC_KILL_GOODS_KEY);

        //购买商品时的表单初始化
        SeckilOrderFormVo vo = new SeckilOrderFormVo();
        RelationEntity relation = this.getById(id);
        BeanUtils.copyProperties(relation,vo);
        vo.setSeckillCount(Integer.valueOf(hashOperations.get(id.toString()).toString()));
        Product product = productFeign.userSelectById(relation.getProductId()).getData(new TypeReference<Product>(){});
        vo.setProductName(product.getName());
        vo.setPayPoint(product.getPayPoint());
        vo.setProductId(product.getId());

        return vo;
    }

    @Override
    public RelationEntity getById(Integer id) {
        //获取操作redis hash类型的操作类
        BoundHashOperations<String,Object ,Object> hashOperations = redisTemplate.boundHashOps(SEC_KILL_GOODS_KEY);

        RelationEntity relation = super.getById(id);
        relation.setSeckillCount(Integer.valueOf(hashOperations.get(id.toString()).toString()));
        return relation;
    }

}